/*
 * @ author madman
 * @ use 公用类
 */
const jwt = require('jsonwebtoken')
var Decimal = require('decimal.js');
import fs from 'fs';
class Utils {
    constructor() {
        this.limt = 10; //分页条数
    }
    //分页静态方法
    /*
     * @options.name              模型路径
     * @options.type              page:分页类型|pop:关联类型|list:列表类型
     * @options.findField         查询字段
     * @options.queryField        过滤字段
     * @options.populate          关联字段
     * @options.populateField     关联过滤字段
     * @options.sortType          排序类型
     * @options.sortVal           排序字段
     * @options.limt              分页数
     */
    async _Page(ctx, options) {
        const moduleName = require(`../../models/${options.name}.model`);
        const pagingParams = { __v: 0 }
        const _findField = options.findField || {}
        const _sort = {}
        let result
        const filterField = { ...pagingParams, ...options.queryField }
        const populateField = options.populateField || ''
        _sort[options.sortType || 'createdAt'] = options.sortVal || -1
        if (options.type === 'page' || options.type === 'pop') {
            // const total = await moduleName.find(_findField).count()  // count方法查询总数有问题，下次aggregate方法
            let total =  await moduleName.aggregate([{
                $match: {
                    $and: [_findField],
                }
            }, {
                $group : {  
                   _id : null,  
                   count: { $sum: 1 }  
                }  
              }  
            ])
            let $total = (total.length > 0 && total[0].count) || 0   // 聚合查询出来的是数组，查不到数据会返回空数组，需要进行判断
            const limt = parseInt(options.limt) || this.limt
            const curPage = parseInt(ctx.query.page) - 1 || 0
            if (options.type === 'pop') {
                result = await moduleName.find(_findField, filterField)
                    .limit(limt)
                    .skip(limt * curPage)
                    .sort(_sort)
                    .populate(options.populate, populateField)
            } else {
                result = await moduleName.find(_findField, filterField)
                    .limit(limt)
                    .skip(limt * curPage)
                    .sort(_sort)
            }
            if (result) {
                return await {
                    data: result,
                    total: $total,
                    pages: Math.ceil($total / limt)
                }
            }
        } else {
            result = await moduleName.find(_findField, filterField).sort(_sort)
            if (result) {
                return await {
                    data: result
                }
            }
        }

    }
    /*
     * 获取列表分页方法
     * @modelName  传入模型路径
     */
    async getPageList(ctx, modelName) {
        let result = await this._Page(ctx, modelName)
        if (result) {
            return {
                result: result.data,
                total: result.total,
                pages: result.pages
            }
        }
    }
    //生成token
    async createToken(name) {
        const token = jwt.sign({
            name: name
        }, 'secret', { expiresIn: '86400000' });
        return await token;
    }
    //判断token是否有效
    async checkToken(ctx, next) {
        let token = ctx.query.token || ctx.request.token || ctx.cookies.get('token')
        let decoded = jwt.decode(token, 'secret')
        // 监测 token 是否过期
        if (token && decoded && (decoded.exp <= Date.now() / 1000)) {
            return ctx.error({
                code: 401,
                message: 'token过期，请重新登录'
            })
        }
        await next();
    }
    decimal(a, b, type){
        return new Decimal(a)[type](new Decimal(b)).toNumber()
    }
    // 取当2个时间的分钟数s
    diffTime(s) {
        var _s = parseInt(s)
        var h =  Math.floor(_s/60);
        _s =   _s %60;
        return  _s > 0 ? h + 1 : h
    }
    // 获取当前时间后的30天
    currDateTo30() {
      var nowDate = new Date();
      var Day = nowDate.getDate();
      var Month = nowDate.getMonth() + 1;
      var Year = nowDate.getFullYear();
      var Hours = nowDate.getHours()
      var Minutes = nowDate.getMinutes()
      var Seconds = nowDate.getSeconds()
      var $Month = Month + 1
      var currDate = new Date(Year, Month, 0, Hours, Minutes, Seconds);
      var _nowDate = new Date(Year, $Month, 0, Hours, Minutes, Seconds);
      if (Day === currDate.getDate()) {
        Day = _nowDate.getDate()
      } 
      return new Date(Year , Month, Day, Hours, Minutes, Seconds);
    }
    // 2个时间相差多少天
    currDateToDay(nowDate, currDate) {
        var _nowDate = nowDate.getTime();
        var _currDate =currDate.getTime();
        var _dateSpan =  Math.abs(currDate - nowDate);
        var iDays = Math.floor(_dateSpan / (24 * 3600 * 1000));
        console.log(_nowDate, _currDate, _dateSpan, iDays)
        return iDays
      }
    //文件上传类
    async createUpload(ctx) {
        const { files, mid, file } = ctx.upload;
        console.log(ctx.upload)
        if (!files || !file) return ctx.error({ msg: '上传失败!' });
        return ctx.success({ msg: '上传成功!', data: { mid, files, file } });
    }
    // 参数格式化
    objToKeyValue(param, key, encode) { 
        if (param == null) return ''; 
        var paramStr = '',
            t = typeof (param); 
        if (t == 'string' || t == 'number' || t == 'boolean') { 
            paramStr += '&' + key + '=' + ((encode == null || encode) ? encodeURIComponent(param) : param); 
        } else { 
            for (var i in param) { 
                var k = key == null ? i : key + (param instanceof Array ? '[' + i + ']' : '.' + i); 
                paramStr += objToKeyValue(param[i], k, encode) 
            } 
        } 
        return paramStr; 
    }
    // 格式化提交过来的字段，可用于单个字段更新
    _params(_paramsBody, type) {
        const paramsBody = [_paramsBody]
        const _params = {}
        paramsBody.forEach((item) => {
            console.log(item)
            Object.keys(item).forEach((_item) => {
                if (typeof _paramsBody[_item] === 'boolean' || _paramsBody[_item] || _paramsBody[_item] === '') {
                    _params[_item] = _paramsBody[_item]
                }
            })
        })
        return _params
    }
    //微信回调中转页
    wexin_redirect_url(ctx) {
        const redirect_uri = ctx.query.redirect_url
        ctx.redirect(redirect_uri + '?code=' + ctx.query.code + '&state=' + ctx.query.state)
    }
    // 写入目录
    mkdirsSync(dirname){
        if (fs.existsSync(dirname)) {
          return true
        } else {
          if (this.mkdirsSync(path.dirname(dirname))) {
           fs.mkdirSync(dirname)
           return true
          }
        }
        return false
    }
}

export default new Utils;
